﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using TaiwuModFramework.Common.Abstract;
using TaiwuModFramework.Common.Info;
using TaiwuModFramework.Common.Utils;

namespace TaiwuModFramework.Common.Base {
    public class BaseMsgClient : AMsgClient {

        private static ALogger Log { get { return AFwDomain.Log; } }

        /// <summary>
        /// 待发送的消息队列
        /// </summary>
        private ConcurrentQueue<MsgInfo> MsgQueue = new ConcurrentQueue<MsgInfo>();
        private readonly NoBufferShareMemory sm;
        private readonly Thread ProcessThread;
        public string RealPath { get; private set; }
        public bool A { get; private set; }



        public BaseMsgClient(string path, bool isA, int maxMsgSize = 4 << 20, int timeout_ms = 10 * 1000) {
            sm = new NoBufferShareMemory(path, maxMsgSize, isA, timeout_ms);
            A = isA;
            RealPath = sm.RealPath;
            ProcessThread = new Thread(LoopProcess);
            ProcessThread.IsBackground = true;
            ProcessThread.Start();
            Log.Info($"BaseMsgClient{(A ? 'A' : 'B')} 创建完成");
        }

        private void LoopProcess() {
            Log.Info($"BaseMsgClient{(A ? 'A' : 'B')} 开始循环处理消息");
            while(true) {
                try {
                    MsgInfo msg;
                    if(sm.CanRead() && Consumer!=null) {
                        
                        byte[] data = sm.ReadData();
                        msg = MSBinSerializer.Instance.Deseriallize<MsgInfo>(data);
                        Consumer(msg);
                    }
                    if(sm.CanWrite() && MsgQueue.TryDequeue(out msg)) {
                        byte[] data = MSBinSerializer.Instance.Serialize(msg);
                        sm.WriteData(data);
                    }

                }catch(Exception e) {
                    Log.Error(e);
                }
            }

        }



        internal override void Send(MsgInfo msg) {
            if(msg != null) MsgQueue.Enqueue(msg);
        }
    }
}
